//
// Created by alexa on 5/13/2024.
//

#include "CrewRepository.h"

#include <fstream>

#include <nlohmann/json.hpp>

using json = nlohmann::json;

MaintenanceCrew *CrewRepository::findById(string id) {
    return source.getById(id);
}

void CrewRepository::save(MaintenanceCrew *crew) {
    if (!source.getById(crew->getId())) source.add(crew);
    if (!fileSourcePath.empty()) {
        saveDataToFile();
    }
}

void CrewRepository::deleteOne(MaintenanceCrew *crew) {
    if (source.getById(crew->getId())) {
        source.removeById(crew->getId());
    }
    if (!fileSourcePath.empty()) {
        saveDataToFile();
    }
}

vector<MaintenanceCrew *> CrewRepository::findAll() {
    return source.getAll();
}

const string &CrewRepository::getFileSourcePath() const {
    return fileSourcePath;
}

void CrewRepository::setFileSourcePath(const string &fileSourcePath) {
    CrewRepository::fileSourcePath = fileSourcePath;
    if (!fileSourcePath.empty()) {
        loadDataFromFile();
    }
}

void CrewRepository::loadDataFromFile() {
    if (fileSourcePath.empty()) return;
    ifstream file(fileSourcePath);
    if (!file.good()) {
        file.close();
        return;
    }
    json data;
    try {
        data = json::parse(file);
    } catch (json::exception &pass) {
        file.close();
        return;
    }
    if (!data.is_array()) return;
    for (const auto &el: data) {
        try {
            string id = el.at("id");
            vector<string> soldiersIds = el.at("soldiersIds");
            MaintenanceCrew *crew = new MaintenanceCrew();
            crew->setId(id);
            for (const auto &soldierId: soldiersIds) {
                crew->addSoldierId(soldierId);
            }
            this->source.add(crew);
        } catch (json::exception &e) {
            continue;
        }
    }
    file.close();
}

void CrewRepository::saveDataToFile() {
    ofstream file(fileSourcePath);

    json jarr = json::array();

    vector<MaintenanceCrew *> list = findAll();

    for (const auto &el: list) {
        json jobj = json::object();
        jobj["id"] = el->getId();
        jobj["soldiersIds"] = el->getSoldiersIds();
        jarr.push_back(jobj);
    }
    file << jarr.dump(4) << endl;
    file.close();
}

CrewRepository::CrewRepository(const string &fileSourcePath) : fileSourcePath(fileSourcePath) {
    if (!fileSourcePath.empty()) {
        loadDataFromFile();
    }
}

CrewRepository::~CrewRepository() {
    vector<MaintenanceCrew *> list = findAll();
    for (auto &el: list) {
        delete el;
    }
}
